package signHelper.permission.shiro;

import java.util.List;
import java.util.Set;

import org.apache.shiro.SecurityUtils;
import org.apache.shiro.authc.AuthenticationException;
import org.apache.shiro.authc.AuthenticationInfo;
import org.apache.shiro.authc.AuthenticationToken;
import org.apache.shiro.authc.IncorrectCredentialsException;
import org.apache.shiro.authc.SimpleAuthenticationInfo;
import org.apache.shiro.authc.UnknownAccountException;
import org.apache.shiro.authc.UsernamePasswordToken;
import org.apache.shiro.authz.AuthorizationException;
import org.apache.shiro.authz.AuthorizationInfo;
import org.apache.shiro.authz.SimpleAuthorizationInfo;
import org.apache.shiro.crypto.hash.Md5Hash;
import org.apache.shiro.realm.AuthorizingRealm;
import org.apache.shiro.subject.PrincipalCollection;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;

import signHelper.modle.User;
import signHelper.service.UserService;

/**
 * 用户认证
 */
public class ShiroAccountRealm extends AuthorizingRealm {
	public Logger logger = LoggerFactory.getLogger(getClass());

	@Autowired
	private UserService userService;

	// 授权
	@Override
	protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principalCollection) {
		// 因为非正常退出，即没有显式调用 SecurityUtils.getSubject().logout()
		// (可能是关闭浏览器，或超时)，但此时缓存依旧存在(principals)，所以会自己跑到授权方法里。
		if (!SecurityUtils.getSubject().isAuthenticated()) {
			doClearCache(principalCollection);
			SecurityUtils.getSubject().logout();
			return null;
		}
		String username = (String) principalCollection.getPrimaryPrincipal();
		SimpleAuthorizationInfo authorizationInfo = new SimpleAuthorizationInfo();
		User account = new User();
		account.setName(username);
		List<User> accounts = userService.query(account,0,1);
		// 获取权限信息
		if (!accounts.isEmpty()) {
				authorizationInfo.addRole(accounts.get(0).getRole().toString());
			return authorizationInfo;
		} else {
			throw new AuthorizationException();
		}
	}

	// 认证，基于用户名密码
	@Override
	protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken token) throws AuthenticationException {
		UsernamePasswordToken upToken = (UsernamePasswordToken) token;
		String username = upToken.getUsername();
		// 根据用户名查找用户
		User bean=new User();
		bean.setNumber(username);
		List<User> accounts = userService.query(bean, 0, 1);
		if (accounts.size()>0) {
			AuthenticationInfo authcInfo = new SimpleAuthenticationInfo(username, accounts.get(0).getPassword(), this.getName());
			ShiroSessionUtils.setAsLogin(accounts.get(0));
			/**
			 * 关闭浏览器，再打开后，虽然授权缓存了，但是认证是必须的，在认证成功后，清除之前的缓存。
			 */
			clearCache(authcInfo.getPrincipals());

			return authcInfo;
		} else {
			// 认证没有通过
			throw new UnknownAccountException();// 没帐号
		}
	}

}
